home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 October: Mac OS SDK / Dev.CD Oct 97 SDK1.toast / Development Kits (Disc 1) / QuickDraw GX / Programming Stuff / Sample Code / Graphics Samples / Spectacle ƒ / ViewPorts.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-15  |  9.9 KB  |  407 lines  |  [TEXT/KAHL]

  1. /* 
  2.  *    ViewPorts.c
  3.  *
  4.  *    Robert Dierkes,  November 11, 1993
  5.  *
  6.  *    Change History:
  7.  *
  8.  *       11/93    ???        New
  9.  *       4/96        bob        Updated #includes to support changed GX Library names.
  10.  *                        Changed boolean to Boolean.
  11.  *                        Changed fixed to Fixed.
  12.  *                        Added the copyright info.
  13.  *
  14.  *
  15.  *        © Apple Computer, Inc. 1990 - 1996  All rights reserved
  16.  *
  17.  */
  18.  
  19. #include <GXGraphics.h>
  20. #include "GraphicsLibraries.h"
  21. #include <GXEnvironment.h>
  22.  
  23. #include "Object.h"
  24. #include "ViewPorts.h"
  25.  
  26.  
  27.  
  28. /*----------------------*/
  29. /*    Global Declarations    */
  30. /*----------------------*/
  31. gxShape                gObject,
  32.                     gLastObject,
  33.                     gFrame;
  34. Boolean                gIsSquare,
  35.                     gShowFrame,
  36.                     gDoDither,
  37.                     gDoHalftone;
  38. long                gPanesPerSide;
  39.  
  40. /*------------------------------*/
  41. /*    External Declarations     */
  42. /*------------------------------*/
  43. extern    Boolean        gDoAnimation;
  44. extern    Boolean        gCyclePanes;
  45. extern    long        gNextCycle;
  46.  
  47.  
  48. void SetHalftone (gxViewPort vPort, Fixed angle, Fixed frequency, gxDotType method, gxRGBColor *pDotColor);
  49. void SetDitherOrHalftone (gxViewPort vPort, short row, short col);
  50. void SetMapping (gxViewPort vPort, short row, short col, Fixed xCenter, Fixed yCenter);
  51.  
  52.  
  53.     static void
  54. SetHalftone (gxViewPort    vPort,
  55.             Fixed        angle,
  56.             Fixed        frequency,
  57.             gxDotType        method,
  58.             gxRGBColor    *pDotColor)
  59. {
  60.     gxHalftone        tone;
  61.  
  62.     if (! gDoHalftone)
  63.         return;
  64.  
  65.     tone.angle        = angle;
  66.     tone.frequency    = frequency;
  67.     tone.method        = method;
  68.     tone.tinting    = gxLuminanceTint;
  69.  
  70.     tone.dotColor.space             = gxRGBSpace;
  71.     tone.dotColor.profile         = nil;
  72.     tone.dotColor.element.rgb     = *pDotColor;
  73.     
  74.     tone.backgroundColor.space     = gxRGBSpace;
  75.     tone.backgroundColor.profile = nil;
  76.     tone.backgroundColor.element.rgb.red   =
  77.     tone.backgroundColor.element.rgb.green =
  78.     tone.backgroundColor.element.rgb.blue  = (gxColorValue) 0xFFFF;    /* white */
  79.  
  80.     tone.tintSpace = gxRGBSpace;
  81.  
  82.     GXSetViewPortHalftone (vPort, &tone);
  83. }
  84.  
  85.  
  86.     static void
  87. SetDitherOrHalftone (gxViewPort    vPort,
  88.                      short        row,
  89.                      short        col)
  90. {
  91.     gxRGBColor    dotColor;
  92.  
  93.     switch (row % kPaneRepeat)
  94.     {
  95.     case 0:
  96.         switch (col % kPaneRepeat)
  97.         {
  98.         case 0:
  99.             SetRBGColor (dotColor, 0xFFFF, 0, 0);            /* Red */
  100.             SetHalftone (vPort, IntToFixed (0), IntToFixed (4), gxRoundDot, &dotColor);
  101.             break;
  102.         case 1:
  103.             IfSetViewPortDither (false, vPort, 1);
  104.             break;
  105.         case 2:
  106.             SetRBGColor (dotColor, 0xFFFF, 45000, 0);        /* Orange */
  107.             SetHalftone (vPort, IntToFixed (45), IntToFixed (5), gxEllipticDot, &dotColor);
  108.             break;
  109.         case 3:
  110.             IfSetViewPortDither (false, vPort, 1);
  111.             break;
  112.         }
  113.         break;
  114.  
  115.     case 1:
  116.         switch (col % kPaneRepeat)
  117.         {
  118.         case 0:
  119.             IfSetViewPortDither (gDoDither, vPort, 2);
  120.             break;
  121.         case 1:
  122.             SetRBGColor (dotColor, 60000, 60000, 0);        /* Yellow */
  123.             SetHalftone (vPort, IntToFixed (0), IntToFixed (5), gxSpiralDot, &dotColor);
  124.             break;
  125.         case 2:
  126.             IfSetViewPortDither (gDoDither, vPort, 2);
  127.             break;
  128.         case 3:
  129.             SetRBGColor (dotColor, 50000, 0, 50000);        /* Lavender */
  130.             SetHalftone (vPort, IntToFixed (135), IntToFixed (6), gxLineDot, &dotColor);
  131.             break;
  132.         }
  133.         break;
  134.  
  135.     case 2:
  136.         switch (col % kPaneRepeat)
  137.         {
  138.         case 0:
  139.             SetRBGColor (dotColor, 0, 0xFFFF, 0);            /* Green */
  140.              SetHalftone (vPort, IntToFixed (45), IntToFixed (5), gxTriangleDot, &dotColor);
  141.             break;
  142.         case 1:
  143.             IfSetViewPortDither (gDoDither, vPort, 3);
  144.             break;
  145.         case 2:
  146.             SetRBGColor (dotColor, 0, 55000, 65000);        /* Cyan */
  147.             SetHalftone (vPort, IntToFixed (45), IntToFixed (4), gxSquareDot, &dotColor);
  148.             break;
  149.         case 3:
  150.             IfSetViewPortDither (gDoDither, vPort, 3);
  151.             break;
  152.         }
  153.         break;
  154.  
  155.     case 3:
  156.         switch (col % kPaneRepeat)
  157.         {
  158.         case 0:
  159.             IfSetViewPortDither (gDoDither, vPort, 4);
  160.             break;
  161.         case 1:
  162.             SetRBGColor (dotColor, 0, 0, 0xFFFF);            /* Blue */
  163.             SetHalftone (vPort, IntToFixed (45), IntToFixed (6), gxLineDot, &dotColor);
  164.             break;
  165.         case 2:
  166.             IfSetViewPortDither (gDoDither, vPort, 4);
  167.             break;
  168.         case 3:
  169.             SetRBGColor (dotColor, 40000, 40000, 40000);    /* Gray */
  170.             SetHalftone (vPort, IntToFixed (0), IntToFixed (6), gxTriangleDot, &dotColor);
  171.             break;
  172.         }
  173.         break;
  174.     }
  175. }
  176.  
  177.  
  178.     static void
  179. SetMapping (gxViewPort    vPort,
  180.             short        row,
  181.             short        col,
  182.             Fixed        xCenter,
  183.             Fixed        yCenter)
  184. {
  185.     gxMapping        map;
  186.  
  187.     ResetMapping (&map);
  188.  
  189.     if ((row % kPaneRepeat == 0  ||  row % kPaneRepeat == 1)  &&
  190.         (col % kPaneRepeat == 2  ||  col % kPaneRepeat == 3))
  191.             ScaleMapping (&map, fixed1, fixed1 >> 1, xCenter, yCenter);
  192.     else
  193.     if ((row % kPaneRepeat == 2  ||  row % kPaneRepeat == 3)  &&
  194.         (col % kPaneRepeat == 0  ||  col % kPaneRepeat == 1))
  195.             ScaleMapping (&map, fixed1 >> 1, fixed1, xCenter, yCenter);
  196.     else
  197.     if ((row % kPaneRepeat == 1  ||  row % kPaneRepeat == 2)  &&
  198.         (col % kPaneRepeat == 1  ||  col % kPaneRepeat == 2))
  199.             RotateMapping (&map, IntToFixed (30), xCenter, yCenter);
  200.  
  201.     GXSetViewPortMapping (vPort, &map);
  202. }
  203.  
  204.  
  205.     void
  206. ChangeFrame (Rect *pBounds, long numCols, long numRows, Boolean showFrame, gxShape *pFrame)
  207. {
  208.     register
  209.     short        r, c;
  210.     register
  211.     Fixed        left,
  212.                 top,
  213.                 width,
  214.                 height;
  215.     gxShape        pane;
  216.     Rect        bounds;
  217.  
  218.     DisposeShapeAt (pFrame);
  219.     if (! showFrame)
  220.         return;
  221.  
  222.     /* Find width and height of each pane */
  223.     bounds = *pBounds;
  224.     InsetRect (&bounds, FixedToInt (kFrameThickness), FixedToInt (kFrameThickness));
  225.     width    = IntToFixed (bounds.right  - bounds.left) / numCols;
  226.     height    = IntToFixed (bounds.bottom - bounds.top)  / numRows;
  227.  
  228.     /* Start with the outside frame */
  229.     *pFrame = GXNewShape (gxEmptyType);
  230.  
  231.     for (r = 0, top = kFrameThickness; r < numRows; r++)
  232.     {
  233.         for (c = 0, left = kFrameThickness; c < numCols; c++)
  234.         {
  235.             /* Add a pane inside the frame */
  236.             pane = NewShape4 (gxRectangleType, left, top, left + width, top + height);
  237.             GXInsetShape (pane, kFrameThickness);
  238.             AddToShape (*pFrame, pane);
  239.             GXDisposeShape (pane);
  240.  
  241.             left += width;
  242.         }
  243.         top += height;
  244.     }
  245.  
  246.     /* Set other characteristics on the frame */
  247.     SetShapeCommonColor (*pFrame, gxGray);
  248.     GXSetShapeStyleAttributes (*pFrame, gxOutsideFrameStyle);
  249.     GXSetShapeFill (*pFrame, gxClosedFrameFill);
  250.     GXSetShapePen (*pFrame, kFrameThickness << 1);
  251.  
  252.     /* Make the frame a picture so the grow box can be added */
  253.     GXSetShapeType (*pFrame, gxPictureType);
  254.  
  255.     /* Make a grow box in the lower left corner */
  256.     pane = NewShape4 (gxRectangleType, IntToFixed (pBounds->right)  - (kFrameThickness << 1),
  257.                                      IntToFixed (pBounds->bottom) - (kFrameThickness << 1),
  258.                                      IntToFixed (pBounds->right),
  259.                                      IntToFixed (pBounds->bottom));
  260.     SetShapeCommonColor (pane, steel);
  261.     AddToPicture (*pFrame, pane, nil, nil, nil);
  262.     GXDisposeShape (pane);
  263. }
  264.  
  265.  
  266.     static void
  267. ChangeShapeViewPorts (WindowPtr pWindow, long numRows, long numCols,
  268.                         Boolean showFrame, gxShape object)
  269. {
  270.     register
  271.     short        r, c;
  272.     register
  273.     gxViewPort    *pViewPort,
  274.                 *p1stViewPort;
  275.     Fixed        width,
  276.                 height,
  277.                 left,
  278.                 top;
  279.     gxShape        clip;
  280.     gxViewPort    parent;
  281.     gxTransform    xForm;
  282.     Rect        bounds;
  283.  
  284.     if (numRows == 0  ||  numCols == 0)
  285.     {
  286.         DebugStr ("\pAddViewPortsToTransform: Number of rows or columns is zero");
  287.         return;
  288.     }
  289.  
  290.     /* Find width and height of each gxViewPort */
  291.     bounds = pWindow->portRect;
  292.     InsetRect (&bounds, FixedToInt (kFrameThickness), FixedToInt (kFrameThickness));
  293.     width    = IntToFixed (bounds.right  - bounds.left) / numCols;
  294.     height    = IntToFixed (bounds.bottom - bounds.top)  / numRows;
  295.  
  296.     /* Make a gxTransform */
  297.     xForm = GXNewTransform ();
  298.  
  299.     /* Allocate space for viewPorts */
  300.     p1stViewPort = pViewPort = (gxViewPort *) NewPtr (numRows * numCols * sizeof (gxViewPort));
  301.     if (p1stViewPort == nil)
  302.     {
  303.         DebugStr ("\pAddViewPortsToTransform: NewPtr for viewPorts failed");
  304.         return;
  305.     }
  306.  
  307.     parent = GXGetWindowViewPort (pWindow);
  308.  
  309.     for (r = 0, top = kFrameThickness; r < numRows; r++, top += height)
  310.     {
  311.         for (c = 0, left = kFrameThickness; c < numCols; c++, left += width, pViewPort++)
  312.         {
  313.             /* Make a new gxViewPort and set its clip and gxMapping */
  314.             *pViewPort = GXNewViewPort (gxScreenViewDevices);
  315.             GXSetViewPortParent (*pViewPort, parent);
  316.  
  317.             /* Make and set the gxViewPort's clip */
  318.             clip = NewShape4 (gxRectangleType, left, top, left + width, top + height);
  319.             if (showFrame)
  320.                 GXInsetShape (clip, kFrameThickness);
  321.             GXSetViewPortClip (*pViewPort, clip);
  322.             GXDisposeShape (clip);
  323.  
  324.             /* Set the dither or gxHalftone and gxMapping */
  325.             SetDitherOrHalftone (*pViewPort, r, c);
  326.             SetMapping (*pViewPort, r, c, left + (width >> 1), top + (height >> 1));
  327.  
  328.             if (r == 0  &&  c == 0)
  329.                 /* Set the gxTransform's first gxViewPort */
  330.                 GXSetTransformViewPorts (xForm, 1, pViewPort);
  331.             else
  332.                 /* Add successive viewPorts */
  333.                 AddToTransformViewPort (xForm, *pViewPort);
  334.         }
  335.     }
  336.  
  337.     /* Set the object gxShape's gxTransform with all the gxViewPort */
  338.     GXSetShapeTransform (object, xForm);
  339.     GXDisposeTransform (xForm);
  340. }
  341.  
  342.  
  343.     void
  344. InitializeViewPortGlobals (void)
  345. {
  346.     gShowFrame      = true;
  347.     gDoAnimation  = false;
  348.     gDoDither      = true;
  349.     gDoHalftone      = true;
  350.     gIsSquare     = true;
  351.     gObject          = nil;
  352.     gFrame          = nil;
  353.     gPanesPerSide = kInitialPanesPerSide;
  354.     gCyclePanes      = false;
  355.     gNextCycle      = 0;
  356. }
  357.  
  358.  
  359.     void
  360. ChangeViewPorts (WindowPtr pWindow)
  361. {
  362.     ChangeShapeViewPorts (pWindow, gPanesPerSide, gPanesPerSide, gShowFrame, gObject);
  363.     ChangeFrame (&pWindow->portRect, gPanesPerSide, gPanesPerSide, gShowFrame, &gFrame);
  364. }
  365.  
  366.  
  367.     void
  368. InitializeViewPorts (WindowPtr pWindow)
  369. {
  370.     InitializeObject (gIsSquare, kObjectWidth, kObjectHeight, &gObject, &gLastObject);
  371.     ChangeViewPorts (pWindow);
  372. }
  373.  
  374.     void
  375. DisposeViewPorts (WindowPtr pWindow)
  376. {
  377.     gxViewPort    parent,
  378.                 *p1stChild,
  379.                 *pChild;
  380.     long        childCount;
  381.  
  382.     DisposeShapeAt (&gObject);
  383.     DisposeShapeAt (&gLastObject);
  384.     DisposeShapeAt (&gFrame);
  385.  
  386.     if (parent = GXGetWindowViewPort (pWindow))
  387.     {
  388.         if (childCount = GXGetViewPortChildren (parent, nil))
  389.         {
  390.             if (p1stChild = pChild = (gxViewPort *) NewPtrClear (childCount * sizeof (gxViewPort)))
  391.             {
  392.                 (void) GXGetViewPortChildren (parent, p1stChild);
  393.                 while (childCount--)
  394.                     GXDisposeViewPort (*pChild++);
  395.                 DisposePtr ((Ptr) p1stChild);
  396.                 GXDisposeViewPort (parent);
  397.             }
  398.             else
  399.                 DebugStr ("\pDisposeViewPorts: NewPtrClear failed");
  400.         }
  401.         else
  402.             DebugStr ("\pDisposeViewPorts: Parent gxViewPort has no children");
  403.     }
  404.     else
  405.         DebugStr ("\pDisposeViewPorts: Window has no gxViewPort");
  406. }
  407.